package com.lagou.web;

import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.WebApplicationInitializer;

import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.HandlesTypes;
import java.lang.reflect.Modifier;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
@HandlesTypes({WebApplicationInitializer.class})
public class MySpringServletContainerInitializer implements ServletContainerInitializer {
    @Override
    public void onStartup(Set<Class<?>> set, ServletContext servletContext) throws ServletException {
        /**
         * Servlet 3.0+容器启动时将自动扫描类路径以查找实现Spring的 WebApplicationInitializer 接口的所有实现，
         * 将其放进一个Set集合中，提供给ServletContainerInitializer中onStartup方法的第一个参数。
         */
        List<WebApplicationInitializer> initializers = new LinkedList<>();

        if (set != null) {
            for (Class<?> waiClass : set) {
                // 如果该Class 不是接口，不是抽象类，并且是WebApplicationInitializer类型的类
                //仿写springMvc中的实现
                if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) &&
                        WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
                    try {
                        //实例化该类，并加入到initializers集合中
                        initializers.add((WebApplicationInitializer)
                                ReflectionUtils.accessibleConstructor(waiClass).newInstance());
                    }
                    catch (Throwable ex) {
                        throw new ServletException("Failed to instantiate WebApplicationInitializer class", ex);
                    }
                }
            }
        }

        if (initializers.isEmpty()) {
            servletContext.log("WebApplicationInitializer null");
            return;
        }

        servletContext.log(initializers.size() + " Spring WebApplicationInitializers detected on classpath");
        AnnotationAwareOrderComparator.sort(initializers);
        //遍历initializers集合中的类
        for (WebApplicationInitializer initializer : initializers) {
            //调用其onStartup方法
            initializer.onStartup(servletContext);
        }
    }
}
